iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
0
Modern Web

資料視覺化!D3入門到實戰系列 第 16

Day16 實戰!台灣各城市天氣概況_接上open api

  • 分享至 

  • xImage
  •  

今天來到另一個重頭戲,就是接open api拿到實際的天氣資料,我們選用的是這個api:
https://works.ioa.tw/weather/api/doc/index.html

在開始之前,大家應該都已經刻好畫面了,如果還沒的也沒關係,可以直接用我這個commit的程式碼:
https://github.com/yuanchen1103/2020ironman-weather/commit/493e73e6f7c59e7481cc28bcb6f7c6bdc420ec4a


拿資料

在順序上,我們會先用第一個api**「取得所有縣市鄉鎮」**來拿到縣市資料,在拿回來的資料當中我們就能拿到城市的id與名字,整理好以後放到左上角那個dropdown selector裡面。

GET https://works.ioa.tw/weather/api/all.json

在這邊我們統一從App.vue中fetch資料,再以props傳下去各個component裡面。

在methods當中創立一個getCityData()的function,把拿到的response存到data當中,並在created的時候執行他,我們的Select就能直接使用這個array。

getCityData() {
  axios
    .get('https://works.ioa.tw/weather/api/all.json')
    .then(response => {
      this.cityData = response.data.map(city => ({ label: `${city.name}, 台灣`, value: city.id }));
    })
    .catch(error => {
      // eslint-disable-next-line
      console.error(error);
    });
}
created() {
    this.getCityData();
},

在拿到每個城市id以後,我們能watch被選中的城市id,若有變動就執行拿天氣的getWeatherData()

GET https://works.ioa.tw/weather/api/weathers/:id.json
getWeatherData(id) {
  axios
    .get(`https://works.ioa.tw/weather/api/weathers/${id}.json`)
    .then(response => {
      this.weatherData = response.data;
    })
    .catch(error => {
      // eslint-disable-next-line
      console.error(error);
    });
}
watch: {
    selected() {
      this.getWeatherData(this.selected.value);
    }
},

整理資料

接下來就是整理拿到的資料,我們把計算的資料放在computed裡面,這樣如果data有變,計算的結果也會跟著變,然後把結果用prop傳進去component裡面就完成囉。(最近都沒下雨,所以雨量資料都是0 XD)

// 雨量資料
getRainfallData() {
  const { histories } = this.weatherData;
  return histories.map(item => ({
    name: moment(item.at).format('mm:ss'),
    value: item.rainfall
  }));
},
// 溫度資料
getTempChartData() {
  const { histories } = this.weatherData;
  return histories.map(item => ({
    name: moment(item.at).format('mm:ss'),
    value: item.temperature
  }));
},
// 體感溫度資料
getFeltAirChartData() {
  const { histories } = this.weatherData;
  return histories.map(item => ({
    name: moment(item.at).format('mm:ss'),
    value: item.felt_air_temp
  }));
},
// 濕度資料
getHumidityChartData() {
  const { histories } = this.weatherData;
  return histories.map(item => ({
    name: moment(item.at).format('mm:ss'),
    value: item.humidity
  }));
},
// 平均溫度
getAvgTemp() {
  const { histories } = this.weatherData;
  return (sum(histories.map(item => item.temperature)) / histories.length).toFixed(1);
},
// 平均體感溫度
getAvgFeltAir() {
  const { histories } = this.weatherData;
  return (sum(histories.map(item => item.felt_air_temp)) / histories.length).toFixed(1);
},
// 平均濕度
getAvgHumidity() {
  const { histories } = this.weatherData;
  return (sum(histories.map(item => item.humidity)) / histories.length).toFixed(1);
}
<div class="row">
  <LineChartBlock title="Temperature"
                  color="#00BAB6"
                  :icon="temp"
                  :chartData="getTempChartData"
                  :avg="getAvgTemp" />
  <LineChartBlock title="Felt Air"
                  color="#94BF41"
                  :icon="snow"
                  :chartData="getFeltAirChartData"
                  :avg="getAvgFeltAir" />
  <LineChartBlock title="Humidity"
                  color="#F8B904"
                  :icon="water"
                  :chartData="getHumidityChartData"
                  :avg="getAvgHumidity" />
</div>
<div class="row"
     style="margin-top: 40px;">
  <RainfallBlock :chartData="getRainfallData" />
  <SunBlock :sunset="getSun.sunset" :sunrise="getSun.sunrise"/>
</div>

這樣我們的專案就大功告成囉~另外可以針對還在fetching時加上loading動畫,增加使用者體驗。明天將會教大家把完成的專案架到firebase上。


上一篇
Day15 實戰!台灣各城市天氣概況_折線圖互動
下一篇
Day17 實戰!將專案打包部署到firebase
系列文
資料視覺化!D3入門到實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言